/*TP3*/
:-lib(ic).
/*Q3.1*/

tache(Tache):-
	Tache =
	[](	tache(3,[]	,m1,_),
			tache(8,[]	,m1,_),
			tache(8,[4,5]	,m1,_),
			tache(6,[]	,m2,_),
			tache(3,[1]	,m2,_),
			tache(4,[1,7]	,m1,_),
			tache(8,[3,5]	,m1,_),
			tache(6,[4]	,m2,_),
			tache(6,[6,7]	,m2,_),
			tache(6,[9,12]	,m2,_),
			tache(3,[1]	,m2,_),
			tache(6,[7,8]	,m2,_)).

/*Q3.2*/

affiche(Tache):-
	dim(Tache,[Dim]),
	(for(Indice,1,Dim),param(Tache)
	do
		Xi is Tache[Indice],
		writeln(Xi)
	).

/*
Résultats :

tache(T), affiche(T).
tache(3, [], m1, _226)
tache(8, [], m1, _231)
tache(8, [4, 5], m1, _236)
tache(6, [], m2, _245)
tache(3, [1], m2, _250)
tache(4, [1, 7], m1, _257)
tache(8, [3, 5], m1, _266)
tache(6, [4], m2, _275)
tache(6, [6, 7], m2, _282)
tache(6, [9, 12], m2, _291)
tache(3, [1], m2, _300)
tache(6, [7, 8], m2, _307)

T = [](tache(3, [], m1, _226), tache(8, [], m1, _231), tache(8, [4, 5], m1, _236), tache(6, [], m2, _245), tache(3, [1], m2, _250), tache(4, [1, 7], m1, _257), tache(8, [3, 5], m1, _266), tache(6, [4], m2, _275), tache(6, [6, 7], m2, _282), tache(6, [9, 12], m2, _291), tache(3, [1], m2, _300), tache(6, [7, 8], m2, _307))
Yes (0.00s cpu)

*/

/*Q3.3*/

domaines(Tache,Fin):-
	dim(Tache,[Dim]),
	(for(Indice,1,Dim),param(Tache,Fin)
	do
		Xi is Tache[Indice],
		Xi = tache(Duree,_,_,Debut),
		Debut #>= 0,
		Duree+Debut #=< Fin
	).

/*
Résultats :

[eclipse 26]: tache(T),domaines(T,10),affiche(T).
tache(3, [], m1, _434{0 .. 6})
tache(8, [], m1, _550{[0, 1]})
tache(8, [4, 5], m1, _666{[0, 1]})
tache(6, [], m2, _782{0 .. 3})
tache(3, [1], m2, _898{0 .. 6})
tache(4, [1, 7], m1, _1014{0 .. 5})
tache(8, [3, 5], m1, _1130{[0, 1]})
tache(6, [4], m2, _1246{0 .. 3})
tache(6, [6, 7], m2, _1362{0 .. 3})
tache(6, [9, 12], m2, _1478{0 .. 3})
tache(3, [1], m2, _1594{0 .. 6})
tache(6, [7, 8], m2, _1710{0 .. 3})

T = [](tache(3, [], m1, _434{0 .. 6}), tache(8, [], m1, _550{[0, 1]}), tache(8, [4, 5], m1, _666{[0, 1]}), tache(6, [], m2, _782{0 .. 3}), tache(3, [1], m2, _898{0 .. 6}), tache(4, [1, 7], m1, _1014{0 .. 5}), tache(8, [3, 5], m1, _1130{[0, 1]}), tache(6, [4], m2, _1246{0 .. 3}), tache(6, [6, 7], m2, _1362{0 .. 3}), tache(6, [9, 12], m2, _1478{0 .. 3}), tache(3, [1], m2, _1594{0 .. 6}), tache(6, [7, 8], m2, _1710{0 .. 3}))
Yes (0.00s cpu)

*/

/*Q3.4*/

getVarList(Tache,Fin,ListFin):-
	dim(Tache,[Dim]),
	(for(Indice,1,Dim),fromto([],In,Out,List),param(Tache)
	do
		Xi is Tache[Indice],
		Xi = tache(_,_,_,Debut),		
		Out = [Debut|In]
	),
	ListFin = [Fin|List].
	

/*
Résultats:

[eclipse 47]: tache(T),getVarList(T,F,L).         

T = [](tache(3, [], m1, _278), tache(8, [], m1, _283), tache(8, [4, 5], m1, _288), tache(6, [], m2, _297), tache(3, [1], m2, _302), tache(4, [1, 7], m1, _309), tache(8, [3, 5], m1, _318), tache(6, [4], m2, _327), tache(6, [6, 7], m2, _334), tache(6, [9, 12], m2, _343), tache(3, [1], m2, _352), tache(6, [7, 8], m2, _359))
F = F
L = [F, _359, _352, _343, _334, _327, _318, _309, _302, _297, _288, _283, _278]
Yes (0.00s cpu)


[eclipse 49]: tache(T),domaines(T,10),getVarList(T,10,L).

T = [](tache(3, [], m1, _464{0 .. 6}), tache(8, [], m1, _580{[0, 1]}), tache(8, [4, 5], m1, _696{[0, 1]}), tache(6, [], m2, _812{0 .. 3}), tache(3, [1], m2, _928{0 .. 6}), tache(4, [1, 7], m1, _1044{0 .. 5}), tache(8, [3, 5], m1, _1160{[0, 1]}), tache(6, [4], m2, _1276{0 .. 3}), tache(6, [6, 7], m2, _1392{0 .. 3}), tache(6, [9, 12], m2, _1508{0 .. 3}), tache(3, [1], m2, _1624{0 .. 6}), tache(6, [7, 8], m2, _1740{0 .. 3}))
L = [10, _1740{0 .. 3}, _1624{0 .. 6}, _1508{0 .. 3}, _1392{0 .. 3}, _1276{0 .. 3}, _1160{[0, 1]}, _1044{0 .. 5}, _928{0 .. 6}, _812{0 .. 3}, _696{[0, 1]}, _580{[0, 1]}, _464{0 .. 6}]
Yes (0.00s cpu)

*/

/*Q3.5*/

/*
solve(Tache,Fin):-
	tache(Tache),
	domaines(Tache,Fin),
	getVarList(Tache,Fin,L),
	labeling(L).
*/

/*
Résultats:

T = [](tache(3, [], m1, 1), tache(8, [], m1, 0), tache(8, [4, 5], m1, 0), tache(6, [], m2, 0), tache(3, [1], m2, 0), tache(4, [1, 7], m1, 0), tache(8, [3, 5], m1, 0), tache(6, [4], m2, 0), tache(6, [6, 7], m2, 0), tache(6, [9, 12], m2, 0), tache(3, [1], m2, 0), tache(6, [7, 8], m2, 0))
F = 8.
Yes (0.00s cpu, solution 1, maybe more) ? ;

T = [](tache(3, [], m1, 1), tache(8, [], m1, 0), tache(8, [4, 5], m1, 0), tache(6, [], m2, 0), tache(3, [1], m2, 0), tache(4, [1, 7], m1, 0), tache(8, [3, 5], m1, 0), tache(6, [4], m2, 0), tache(6, [6, 7], m2, 0), tache(6, [9, 12], m2, 0), tache(3, [1], m2, 0), tache(6, [7, 8], m2, 0))
F = 8
...
*/

/*Q3.6*/

precedences(Tache):-
	dim(Tache,[Dim]),
	(for(Indice,1,Dim),param(Tache)
	do
		Elem is Tache[Indice],
		Elem = tache(_,Noms,_,Debut),
		(foreach(Xe,Noms),param(Tache,Debut)
		do
			X is Tache[Xe],
			X = tache(Du,_,_,De),
			Debut #>= Du+De
		)
	).

/*
Résultats:

solve(T, F).

T = [](tache(3, [], m1, 0), tache(8, [], m1, 0), tache(8, [4, 5], m1, 6), tache(6, [], m2, 0), tache(3, [1], m2, 3), tache(4, [1, 7], m1, 22), tache(8, [3, 5], m1, 14), tache(6, [4], m2, 6), tache(6, [6, 7], m2, 26), tache(6, [9, 12], m2, 32), tache(3, [1], m2, 3), tache(6, [7, 8], m2, 22))
F = 38
Yes (0.00s cpu, solution 1, maybe more) ? ;

T = [](tache(3, [], m1, 0), tache(8, [], m1, 1), tache(8, [4, 5], m1, 6), tache(6, [], m2, 0), tache(3, [1], m2, 3), tache(4, [1, 7], m1, 22), tache(8, [3, 5], m1, 14), tache(6, [4], m2, 6), tache(6, [6, 7], m2, 26), tache(6, [9, 12], m2, 32), tache(3, [1], m2, 3), tache(6, [7, 8], m2, 22))
F = 38

*/

/*Q3.7*/

conflits(Tache):-
	dim(Tache,[Dim]),
	(for(Indice,1,Dim),param(Tache,Dim)
	do
		Elem is Tache[Indice],
		I is Indice+1,
		(for(Indice2,I,Dim),param(Tache,Elem)
		do
			X is Tache[Indice2],
			test(Elem,X)
		)
	).
	
test(tache(_,_,M1,_),tache(_,_,M2,_)):-
	\=(M1,M2).
test(tache(Duree1,_,M,Debut1),tache(Duree2,_,M,Debut2)):-
	(Debut2+Duree2 #=< Debut1) or (Debut1+Duree1 #=< Debut2).

/*
Résultats

solve(T, F).

T = [](tache(3, [], m1, 0), tache(8, [], m1, 29), tache(8, [4, 5], m1, 9), tache(6, [], m2, 0), tache(3, [1], m2, 6), tache(4, [1, 7], m1, 25), tache(8, [3, 5], m1, 17), tache(6, [4], m2, 12), tache(6, [6, 7], m2, 31), tache(6, [9, 12], m2, 37), tache(3, [1], m2, 9), tache(6, [7, 8], m2, 25))
F = 43

*/

solve(Tache,Fin):-
	tache(Tache),
	domaines(Tache,Fin),
	precedences(Tache),
	conflits(Tache),
	getVarList(Tache,Fin,L),
	labeling(L).

/*
Q3.8

La solution proposée par eclipse paraît optimale. En effet, elle correspond au calcul de la date au plus tôt des algorithmes d'optimisation de graphes.
C'est le but de la propagation des contraintes.
*/
